package me.flyray.crm.core.biz.customer;

import java.math.BigDecimal;
import java.util.Date;

import me.flyray.common.enums.*;
import me.flyray.common.exception.BusinessException;
import me.flyray.common.msg.ResponseCode;
import me.flyray.common.util.CurrencyUtils;
import me.flyray.common.util.SnowFlake;
import me.flyray.crm.core.entity.*;
import me.flyray.crm.core.mapper.*;
import me.flyray.crm.facade.request.OutAccountRequest;
import me.flyray.crm.facade.request.UnfreezeAndOutAccountRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import me.flyray.common.util.EntityUtils;
import me.flyray.common.util.MD5;

import lombok.extern.slf4j.Slf4j;

/**
 * 个人或者商户解冻并出账接口
 */
@Slf4j
@Transactional(rollbackFor = Exception.class)
@Service
public class CustomerOutAccountBiz {

	@Value("${crm.account.balanceSaltValue}")
	private String balanceSaltValue;
    @Autowired
    private CustomerBaseMapper customerBaseMapper;
	@Autowired
	private MerchantAccountJournalMapper merchantAccountJournalMapper;
	@Autowired
	private MerchantAccountMapper merchantAccountMapper;
	@Autowired
	private UnfreezeJournalMapper unfreezeJournalMapper;
	@Autowired
	private PersonalAccountMapper personalAccountMapper;
	@Autowired
	private PersonalAccountJournalMapper personalAccountJournalMapper;
	@Autowired
	private CustomerIntoAccountBiz customerIntoAccountBiz;

	/**
	 * 个人或者商户解冻并出账接口
	 * 若是商户：
	 * 1.商户账户冻结金额扣除
	 * 2.新增商户流水记录、解冻流水记录
	 * 若是个人：
	 * 1.个人账户冻结金额扣除
	 * 2.新增个人账户流水记录、解冻流水记录
	 */
	public void unfreezeAndOutAccount(UnfreezeAndOutAccountRequest unFreezeAndOutAccountRequest) {
		log.info("个人或者商户解冻并出账接口-请求参数：{}" + EntityUtils.beanToMap(unFreezeAndOutAccountRequest));
		/**
		 * 根据冻结流水号查询是否被解冻
		 * */
        //查询客户信息中的商户号和个人编号
        CustomerBase customerBase = new CustomerBase();
        customerBase.setPlatformId(unFreezeAndOutAccountRequest.getPlatformId());
        customerBase.setCustomerId(unFreezeAndOutAccountRequest.getCustomerId());
        customerBase = customerBaseMapper.selectOne(customerBase);

		UnfreezeJournal queryUnfreezeJournal = new UnfreezeJournal();
		queryUnfreezeJournal.setFreezeId(unFreezeAndOutAccountRequest.getFreezeId());
		UnfreezeJournal unfreezeJournal = unfreezeJournalMapper.selectOne(queryUnfreezeJournal);
		if(null!=unfreezeJournal){
			log.info("个人或者商户解冻并出账接口--冻结资金已解冻");
			throw new BusinessException(ResponseCode.UNFREEZE_IS_EXIST);
		}
		if(unFreezeAndOutAccountRequest.getCustomerType().equals(CustomerType.CUST_MERCHANT.getCode())){
			MerchantAccount queryMerchantAccount=new MerchantAccount();
			queryMerchantAccount.setPlatformId(unFreezeAndOutAccountRequest.getPlatformId());
			queryMerchantAccount.setCustomerId(unFreezeAndOutAccountRequest.getCustomerId());
			queryMerchantAccount.setMerchantId(customerBase.getMerchantId());
			queryMerchantAccount.setMerchantType((unFreezeAndOutAccountRequest.getMerchantType()));
			queryMerchantAccount.setAccountType(unFreezeAndOutAccountRequest.getAccountType());
			MerchantAccount merchantAccount= merchantAccountMapper.selectOne(queryMerchantAccount);
			if(null!=merchantAccount&&merchantAccount.getStatus().equals(AccountState.normal.getCode())){
				if (!MD5.sign(CurrencyUtils.decimaltoString(merchantAccount.getAccountBalance()), balanceSaltValue, "utf-8").equals(merchantAccount.getCheckSum())) {
					log.info("个人或者商户解冻并出账接口-返回参数。。。。。。{}", merchantAccount);
					throw new BusinessException(ResponseCode.MER_ACC_BALANCE_NOT_MATE);
				}
				//商户账户余额不足
				if(merchantAccount.getFreezeBalance().compareTo(new BigDecimal(unFreezeAndOutAccountRequest.getUnfreezeAmt()))<0){
					log.info("个人或者商户解冻并出账接口-返回参数。。。。。。{}", merchantAccount);
					throw new BusinessException(ResponseCode.MER_ACC_BALANCE_NOT_ENOUGH);
				}
				merchantAccount.setFreezeBalance(merchantAccount.getFreezeBalance().subtract(new BigDecimal(unFreezeAndOutAccountRequest.getUnfreezeAmt())));
				merchantAccount.setCheckSum(MD5.sign(CurrencyUtils.decimaltoString(merchantAccount.getAccountBalance()), balanceSaltValue, "utf-8"));
				merchantAccountMapper.updateByPrimaryKeySelective(merchantAccount);

				//如果交易类型是营收则往总交易账户增加交易金额
				if (TradeType.PAYRECEIPT.getCode().equals(unFreezeAndOutAccountRequest.getTradeType())){
					MerchantAccount totalAccount = new MerchantAccount();
					totalAccount.setPlatformId(unFreezeAndOutAccountRequest.getPlatformId());
					totalAccount.setCustomerId(unFreezeAndOutAccountRequest.getCustomerId());
					totalAccount.setMerchantId(customerBase.getMerchantId());
					totalAccount.setMerchantType(unFreezeAndOutAccountRequest.getMerchantType());
					totalAccount.setAccountType(AccountType.TX_TOTAL.getCode());
					MerchantAccount existTotalAccount = merchantAccountMapper.selectOne(totalAccount);
					if (existTotalAccount == null){
						totalAccount.setAccountBalance(new BigDecimal(unFreezeAndOutAccountRequest.getUnfreezeAmt()));
						totalAccount.setCheckSum(MD5.sign(totalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
						totalAccount.setUpdateTime(new Date());
						merchantAccountMapper.insertSelective(totalAccount);
					}else {
						totalAccount.setAccountBalance(existTotalAccount.getAccountBalance().add(new BigDecimal(unFreezeAndOutAccountRequest.getUnfreezeAmt())));
						totalAccount.setCheckSum(MD5.sign(existTotalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
						totalAccount.setUpdateTime(new Date());
						merchantAccountMapper.updateByPrimaryKeySelective(totalAccount);
					}
				}
			}else{
				log.info("个人或者商户解冻并出账接口--商户账户不存在或者被账户被冻结");
				throw new BusinessException(ResponseCode.MER_ACC_NOTEXIST);
			}
			MerchantAccountJournal merAccountJournal=new MerchantAccountJournal();
			merAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			merAccountJournal.setPlatformId(unFreezeAndOutAccountRequest.getPlatformId());
			merAccountJournal.setCustomerId(unFreezeAndOutAccountRequest.getMerchantId());
			merAccountJournal.setMerchantId(unFreezeAndOutAccountRequest.getMerchantId());
			merAccountJournal.setMerchantName(unFreezeAndOutAccountRequest.getMerchantName());
			merAccountJournal.setFromAccount(merchantAccount.getAccountId());
			merAccountJournal.setToAccount(unFreezeAndOutAccountRequest.getToAccount());
			merAccountJournal.setToAccountName(unFreezeAndOutAccountRequest.getToAccountName());
			merAccountJournal.setOrderNo(unFreezeAndOutAccountRequest.getOrderNo());
			//出账
			merAccountJournal.setInOutFlag(InOutFlag.out.getCode());
			merAccountJournal.setTradeAmt(new BigDecimal(unFreezeAndOutAccountRequest.getUnfreezeAmt()));
			merAccountJournal.setTradeType(unFreezeAndOutAccountRequest.getTradeType());
			merAccountJournal.setCreateTime(new Date());
			merchantAccountJournalMapper.insertSelective(merAccountJournal);
		}
		/**
		 * 客户类型-若是个人 : 则需要个人账户余额增加、新增个人账户流水记录
		 * */
		if(unFreezeAndOutAccountRequest.getCustomerType().equals(CustomerType.CUST_PERSONAL.getCode())){
			PersonalAccount queryPersonalAccount = new PersonalAccount();
			queryPersonalAccount.setPlatformId(unFreezeAndOutAccountRequest.getPlatformId());
			queryPersonalAccount.setPersonalId(customerBase.getPersonalId());
			queryPersonalAccount.setAccountType(unFreezeAndOutAccountRequest.getAccountType());
			PersonalAccount personalAccount = personalAccountMapper.selectOne(queryPersonalAccount);
			if(null!=personalAccount&&personalAccount.getStatus().equals(AccountState.normal.getCode())){
				if(!MD5.sign(CurrencyUtils.decimaltoString(personalAccount.getAccountBalance()), balanceSaltValue, "utf-8").equals(personalAccount.getCheckSum())){
					log.info("个人或者商户解冻并出账接口--个人账户余额不匹配");
					throw new BusinessException(ResponseCode.PER_ACC_BALANCE_NOT_MATE);
				}
				personalAccount.setFreezeBalance(personalAccount.getFreezeBalance().subtract(new BigDecimal(unFreezeAndOutAccountRequest.getUnfreezeAmt())));
				personalAccountMapper.updateByPrimaryKeySelective(personalAccount);
			}else{
				log.info("个人或者商户解冻并出账接口--个人账户不存在或者被冻结");
				throw new BusinessException(ResponseCode.PER_ACC_NOTEXIST);
			}
			PersonalAccountJournal personalAccountJournal=new PersonalAccountJournal();
			personalAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			personalAccountJournal.setPlatformId(unFreezeAndOutAccountRequest.getPlatformId());
			personalAccountJournal.setPersonalId(customerBase.getPersonalId());
			personalAccountJournal.setAccountId(personalAccount.getAccountId());
			personalAccountJournal.setAccountType(personalAccount.getAccountType());
			personalAccountJournal.setOrderNo(unFreezeAndOutAccountRequest.getOrderNo());
			//来往标志  1：入账   2：出账
			personalAccountJournal.setInOutFlag(InOutFlag.out.getCode());
			personalAccountJournal.setTradeAmt(new BigDecimal(unFreezeAndOutAccountRequest.getUnfreezeAmt()));
			//交易类型（支付:01，退款:02，提现:03，充值:04）
			personalAccountJournal.setTradeType(unFreezeAndOutAccountRequest.getTradeType());
			personalAccountJournal.setCreateTime(new Date());
			personalAccountJournalMapper.insertSelective(personalAccountJournal);
		}
		/***
		 * 新增解冻流水记录
		 * */
		queryUnfreezeJournal.setJournalId(String.valueOf(SnowFlake.getId()));
		queryUnfreezeJournal.setOrderNo(unFreezeAndOutAccountRequest.getOrderNo());
		//交易类型（支付:01，退款:02，提现:03，充值:04）
		queryUnfreezeJournal.setTradeType(unFreezeAndOutAccountRequest.getTradeType());
		queryUnfreezeJournal.setUnfreezeBalance(new BigDecimal(unFreezeAndOutAccountRequest.getUnfreezeAmt()));
		queryUnfreezeJournal.setCreateTime(new Date());
		unfreezeJournalMapper.insertSelective(queryUnfreezeJournal);
	}

	/**
	 * 个人或者商户直接出账接口
	 * 若是商户:
	 * 1.商户账户余额扣除，2.新增商户账户流水
	 * 若是个人:
	 * 1.个人账户余额扣除  2.新增个人账户流水
	 */
	public void outAccount(OutAccountRequest outAccountRequest) {
		log.info("个人或者商户直接出账接口-请求参数：{}" + EntityUtils.beanToMap(outAccountRequest));

        //查询客户信息中的商户号和个人编号
        CustomerBase customerBase = new CustomerBase();
        customerBase.setPlatformId(outAccountRequest.getPlatformId());
        customerBase.setCustomerId(outAccountRequest.getCustomerId());
        customerBase = customerBaseMapper.selectOne(customerBase);

		if(outAccountRequest.getCustomerType().equals(CustomerType.CUST_MERCHANT.getCode())){
			/**
			 * 修改商户账户余额
			 * */
			MerchantAccount queryMerchantAccount=new MerchantAccount();
			queryMerchantAccount.setPlatformId(outAccountRequest.getPlatformId());
			queryMerchantAccount.setMerchantId(customerBase.getMerchantId());
			queryMerchantAccount.setMerchantType(outAccountRequest.getMerchantType());
			queryMerchantAccount.setAccountType(outAccountRequest.getAccountType());
			MerchantAccount merchantAccount= merchantAccountMapper.selectOne(queryMerchantAccount);
			if(null!=merchantAccount&&merchantAccount.getStatus().equals(AccountState.normal.getCode())){
				//校验商户账户余额是否匹配  和商户账户余额是否充足
				if(!MD5.sign(CurrencyUtils.decimaltoString(merchantAccount.getAccountBalance()), balanceSaltValue, "utf-8").equals(merchantAccount.getCheckSum())){
					throw new BusinessException(ResponseCode.MER_ACC_BALANCE_NOT_MATE);
				}
				if(merchantAccount.getAccountBalance().compareTo(new BigDecimal(outAccountRequest.getOutAccAmt())) < 0){
					log.info("个人或者商户直接出账接口 返回参数。。。。。。{}", merchantAccount);
					throw new BusinessException(ResponseCode.MER_ACC_BALANCE_NOT_ENOUGH);
				}
				BigDecimal newBlance = merchantAccount.getAccountBalance().subtract(new BigDecimal(outAccountRequest.getOutAccAmt()));
				merchantAccount.setAccountBalance(newBlance);
				merchantAccount.setCheckSum(MD5.sign(newBlance.toString(), balanceSaltValue, "utf-8"));
				merchantAccountMapper.updateByPrimaryKeySelective(merchantAccount);
			}else{
				log.info("个人或者商户直接出账接口--商户账户不存在或者被冻结");
				throw new BusinessException(ResponseCode.MER_ACC_NOTEXIST);
			}
			/***
			 * 新增商户账户流水记录
			 * */
			MerchantAccountJournal merAccountJournal=new MerchantAccountJournal();
			merAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			merAccountJournal.setPlatformId(outAccountRequest.getPlatformId());
			merAccountJournal.setMerchantId(customerBase.getMerchantId());
			merAccountJournal.setFromAccount(merchantAccount.getAccountId());
			merAccountJournal.setOrderNo(outAccountRequest.getOrderNo());
			//出账
			merAccountJournal.setInOutFlag(InOutFlag.out.getCode());
			merAccountJournal.setTradeAmt(new BigDecimal(outAccountRequest.getOutAccAmt()));
			//交易类型（支付:01，退款:02，提现:03，充值:04）
			merAccountJournal.setTradeType(outAccountRequest.getTradeType());
			merAccountJournal.setCreateTime(new Date());
			merchantAccountJournalMapper.insertSelective(merAccountJournal);
		}

		if(outAccountRequest.getCustomerType().equals(CustomerType.CUST_PERSONAL.getCode())){
			PersonalAccount queryPersonalAccount = new PersonalAccount();
			queryPersonalAccount.setPlatformId(outAccountRequest.getPlatformId());
			queryPersonalAccount.setPersonalId(customerBase.getPersonalId());
			queryPersonalAccount.setAccountType(outAccountRequest.getAccountType());
			PersonalAccount personalAccount = personalAccountMapper.selectOne(queryPersonalAccount);
			if(null!=personalAccount&&personalAccount.getStatus().equals(AccountState.normal.getCode())){
				if(!MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(personalAccount.getCheckSum())){
					log.info("个人或者商户直接出账接口 返回参数。。。。。。{}", personalAccount);
					throw new BusinessException(ResponseCode.PER_ACC_BALANCE_NOT_MATE);
				}
				personalAccount.setAccountBalance(personalAccount.getAccountBalance().subtract(new BigDecimal(outAccountRequest.getOutAccAmt())));
				personalAccount.setCheckSum(MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
				personalAccountMapper.updateByPrimaryKeySelective(personalAccount);
			}else{
				log.info("个人或者商户直接出账接口--个人账户不存在或者被冻结");
				throw new BusinessException(ResponseCode.PER_ACC_NOTEXIST);
			}
			/***
			 * 新增个人账户流水记录
			 * */
			PersonalAccountJournal personalAccountJournal=new PersonalAccountJournal();
			personalAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			personalAccountJournal.setPlatformId(outAccountRequest.getPlatformId());
			personalAccountJournal.setPersonalId(customerBase.getPersonalId());
			personalAccountJournal.setAccountId(personalAccount.getAccountId());
			personalAccountJournal.setAccountType(personalAccount.getAccountType());
			personalAccountJournal.setOrderNo(outAccountRequest.getOrderNo());
			//来往标志  1：入账   2：出账
			personalAccountJournal.setInOutFlag(InOutFlag.out.getCode());
			personalAccountJournal.setTradeAmt(new BigDecimal(outAccountRequest.getOutAccAmt()));
			//交易类型（支付:01，退款:02，提现:03，充值:04）
			personalAccountJournal.setTradeType(outAccountRequest.getTradeType());
			personalAccountJournal.setCreateTime(new Date());
			personalAccountJournalMapper.insertSelective(personalAccountJournal);
		}
	}


}
